package com.heima.article.service.impl;


import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.heima.article.mapper.ApArticleConfigMapper;
import com.heima.article.mapper.ApArticleContentMapper;
import com.heima.article.mapper.ApArticleMapper;
import com.heima.article.service.ApArticleService;
import com.heima.article.service.FreemarkerService;
import com.heima.common.exception.CustomException;
import com.heima.model.article.dtos.ArticleDto;
import com.heima.model.article.dtos.ArticleHomeDto;
import com.heima.model.article.dtos.CollectionBehaviorDto;
import com.heima.model.article.pojos.ApArticle;
import com.heima.model.article.pojos.ApArticleConfig;
import com.heima.model.article.pojos.ApArticleContent;
import com.heima.model.article.pojos.ApCommentsVo;
import com.heima.model.behavior.dtos.LikeBehaviorDto;
import com.heima.model.behavior.dtos.ReadBehaviorDto;
import com.heima.model.common.dtos.PageResponseResult;
import com.heima.model.common.dtos.ResponseResult;
import com.heima.model.common.enums.AppHttpCodeEnum;
import com.heima.model.wemedia.dtos.GraphicDataParametersDto;
import com.heima.model.wemedia.dtos.WmCommentDto;
import com.heima.model.wemedia.pojos.ImageAndTextData;
import com.heima.model.wemedia.pojos.NewPage;
import com.heima.utils.common.DateUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * @author jack
 * @data 2024 11:30
 */
@Service
@Transactional
@Slf4j
public class ApArticleServiceImpl extends ServiceImpl<ApArticleMapper, ApArticle> implements ApArticleService {


    @Autowired
    private ApArticleMapper apArticleMapper;
    @Autowired
    private ApArticleConfigMapper apArticleConfigMapper;
    @Autowired
    private ApArticleContentMapper apArticleContentMapper;
    @Autowired
    private FreemarkerService freemarkerService;

    /**
     * app文章加载
     *
     * @param homeDto 筛选条件
     * @param type    控制开关：1 表示加载首页和加载更多  2:表示加载更新
     * @return
     */
    @Override
    public ResponseResult load(ArticleHomeDto homeDto, int type) {
        List<ApArticle> list = apArticleMapper.load(homeDto, type);
        return ResponseResult.okResult(list);
    }

    /**
     * 同步自媒体文章到app端
     *
     * @param articleDto
     * @return
     */
    @Override
    public ResponseResult saveOrUpdateArticle(ArticleDto articleDto) {
        ApArticle article = new ApArticle();
        BeanUtils.copyProperties(articleDto, article);

        //1. 判断有没有id
        if (articleDto.getId() == null) {
            //没有：就新增   -- ap_article, ap_article_config, ap_article_content
            apArticleMapper.insert(article);
            articleDto.setId(article.getId());

            ApArticleConfig config = new ApArticleConfig(article.getId());
            apArticleConfigMapper.insert(config);

            ApArticleContent content = new ApArticleContent();
            content.setContent(articleDto.getContent());
            content.setArticleId(article.getId());
            apArticleContentMapper.insert(content);

        } else {
            //有：就修改     -- ap_article, ap_article_content
            apArticleMapper.updateById(article);

            ApArticleContent content = apArticleContentMapper.selectOne(Wrappers.<ApArticleContent>lambdaQuery()
                    .eq(ApArticleContent::getArticleId, articleDto.getId()));
            content.setContent(articleDto.getContent());
            apArticleContentMapper.updateById(content);
        }

        //生成文章的详情页
        freemarkerService.buildPage(articleDto);

        //2. 将文章id返回给调用者
        return ResponseResult.okResult(String.valueOf(article.getId()));
    }

    /**
     * 文章上下架
     *
     * @param map
     */
    @Override
    public void downOrUpArticle(Map map) {
        //先拿到文章id和enable的值
        String articleId = map.get("articleId").toString();
        Short enable = Short.valueOf(map.get("enable").toString());

        boolean isDown = false;      //默认上架
        if (enable == 0) {
            isDown = true;
        }

        ApArticleConfig config = new ApArticleConfig();
        config.setArticleId(Long.valueOf(articleId));
        config.setIsDown(isDown);
        apArticleConfigMapper.update(config, Wrappers.<ApArticleConfig>lambdaUpdate()
                .set(ApArticleConfig::getIsDown, isDown)
                .eq(ApArticleConfig::getArticleId, articleId));

    }

    @Autowired
    private MongoTemplate mongoTemplate;

    @Override
    public PageResponseResult getComments(WmCommentDto dto) {
        //校验参数
        if (dto == null) {
            throw new CustomException(AppHttpCodeEnum.PARAM_INVALID);
        }
        //校验页码参数
        dto.checkParam();
        //创建分页对象
        //List<ApArticle> list = apArticleMapper.selectComments(wmCommentDto);
        Integer currentPage = dto.getPage();
        dto.setPage((dto.getPage() - 1) * dto.getSize());
        List<Long> articleId = dto.getArticleId();
        //评论总量
        List<ApCommentsVo> list = apArticleMapper.selectComments(dto);
        for (ApCommentsVo apCommentsVo : list) {
            if (apCommentsVo.getComments() == null) {
                apCommentsVo.setComments(0L);
            }
        }
        int count = apArticleMapper.findNewsCommentsCount(dto);
       /* //long iii = 1748647893784465410L;
        if(articleId==null||articleId.size()==0){
            throw new CustomException(AppHttpCodeEnum.PARAM_REQUIRE);
        }
        long count2=0;
        //创建一个map集合
        Map<Long, Long> map=new HashMap<>();
        //统计评论的个数
        CountTheNumberOfComments(dto, articleId, map);
        //查询aparticle表的数据
        List<ApCommentsVo> list = apArticleMapper.selectComments(dto);
        //判断数据是否》0
        if(list.size()>0&&list!=null){
            for (ApCommentsVo apCommentsVo : list) {
                //获取map的键然后在赋值评论数量
                if(map.containsKey(apCommentsVo.getId())){
                    apCommentsVo.setComments(map.get(apCommentsVo.getId()));
                }else {
                    apCommentsVo.setComments(0L);
                }
            }
        }*/
        PageResponseResult responseResult = new PageResponseResult(currentPage, dto.getSize(), count);
        //responseResult.ok(AppHttpCodeEnum.SUCCESS.getCode(),list,AppHttpCodeEnum.SUCCESS.getErrorMessage());
        responseResult.setData(list);
        return responseResult;
    }


   /* private void CountTheNumberOfComments(WmCommentDto dto, List<Long> articleId, Map<Long, Long> map) {
        long count2;
        for (Long aLong : articleId) {
            //遍历articleId对mongoTemplate进行查询
            Query query = Query.query(Criteria.where(BehaviorEnums.ENTRY_ID).is(aLong));
            //获取评论表的数量
            long count1 = mongoTemplate.count(query, ApComment.class);
            //获取评论表的实体
            Query query2 = Query.query(Criteria.where(BehaviorEnums.ENTRY_ID).in(articleId));
            //查询回复评论表的实体在进行遍历
            List<ApComment> apComments = mongoTemplate.find(query2, ApComment.class);
            for (ApComment apComment : apComments) {
                //判断回复评论表的id是否等于回复评论表的id
                //并且统计出回复评论表的实体的个数
                Query query1 = Query.query(Criteria.where(BehaviorEnums.COMMENT_ID).is(apComment.getId()).where(BehaviorEnums.AUTHOR_IDS).is(dto.getUserId()));
                count2 = mongoTemplate.count(query1, ApCommentRepay.class);
                //如果等于就将回复评论表的实体的个数加到map中
               map.put(aLong,count1+count2);
            }
        }
    }*/

    @Override
    public ResponseResult addLike(LikeBehaviorDto likeBehaviorDto) {
        // 添加文章的喜欢数量
        int likeCount = 0;
        ApArticle apArticle = apArticleMapper.selectById(likeBehaviorDto.getArticleId());
        if (apArticle.getLikes() == null) {
            apArticle.setLikes(likeCount);
        }
        if (apArticle != null && likeBehaviorDto.getOperation() == 0) {
            ApArticle article = new ApArticle();
            article.setId(likeBehaviorDto.getArticleId());
            article.setLikes(apArticle.getLikes() + 1);
            apArticleMapper.updateById(article);
        } else {
            ApArticle article = new ApArticle();
            article.setId(likeBehaviorDto.getArticleId());
            article.setLikes(apArticle.getLikes() - 1);
            apArticleMapper.updateById(article);
        }
        return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);
    }

    /**
     * 增加阅读量
     *
     * @param readBehaviorDto 读取行为dto
     * @return {@link ResponseResult}
     */
    @Override
    public ResponseResult readBehavior(ReadBehaviorDto readBehaviorDto) {
        Integer readCount = 0;
        ApArticle apArticle = apArticleMapper.selectById(readBehaviorDto.getArticleId());
        if (apArticle.getViews() == null) {
            apArticle.setViews(readCount);
        }
        ApArticle article = new ApArticle();
        article.setId(Long.valueOf(readBehaviorDto.getArticleId()));
        article.setViews(readBehaviorDto.getCount());
        apArticleMapper.updateById(article);
        return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);
    }

    /**
     * 添加收藏数量
     *
     * @param collectionBehaviorDto 集合行为dto
     * @return {@link ResponseResult}
     */
    @Override
    public ResponseResult addCollection(CollectionBehaviorDto collectionBehaviorDto) {
        int collectionCount = 0;
        ApArticle article = apArticleMapper.selectById(collectionBehaviorDto.getEntryId());
        if (article.getCollection() == null) {
            article.setCollection(collectionCount);
        }
        ApArticle apArticle = new ApArticle();
        apArticle.setId(Long.valueOf(collectionBehaviorDto.getEntryId()));
        if (collectionBehaviorDto.getOperation() == 0) {
            //0的话是收藏+1
            apArticle.setCollection(article.getCollection() + 1);
        } else {
            //1的话是取消收藏则 -1
            apArticle.setCollection(article.getCollection() - 1);
        }
        apArticleMapper.updateById(apArticle);
        return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);
    }

    @Override
    public ResponseResult addComment(Long articleId) {
        ApArticle article = apArticleMapper.selectById(articleId);
        Integer comment = article.getComment();
        article.setComment(++comment);
        apArticleMapper.updateById(article);
        return ResponseResult.okResult(comment);
    }


    /**
     * 图形和文本数据
     *
     * @param graphicDataParametersDto 图形数据参数dto
     * @return {@link ResponseResult}
     */
    @Override
    public ResponseResult graphicAndTextualData(GraphicDataParametersDto graphicDataParametersDto) {
        ImageAndTextData imageAndTextData = apArticleMapper.graphicAndTextualData(graphicDataParametersDto);
        return ResponseResult.okResult(imageAndTextData);
    }

    /**
     * 查询图文页面列表
     *
     * @param newPageDto 新页面dto
     * @return {@link ResponseResult}
     */
    @Override
    public PageResponseResult newPage(NewPage newPageDto) {
        //设置分页参数
        newPageDto.checkParam();
        //数据类型转换
        Date beginDate = DateUtils.stringToDate(newPageDto.getBeginDate(), "yyyy-MM-dd");
        Date endDate = DateUtils.stringToDate(newPageDto.getEndDate(), "yyyy-MM-dd");
        IPage page = new Page(newPageDto.getPage(), newPageDto.getSize());
        //查询需要的数据
        LambdaQueryWrapper<ApArticle> queryWrapper = Wrappers.<ApArticle>lambdaQuery()
                .eq(ApArticle::getAuthorId, newPageDto.getUserId())
                .between(ApArticle::getPublishTime, beginDate, endDate)
                .select(ApArticle::getId, ApArticle::getTitle, ApArticle::getViews, ApArticle::getComment, ApArticle::getCollection, ApArticle::getLikes);
        queryWrapper.orderByDesc(ApArticle::getPublishTime);
        page = page(page, queryWrapper);
        PageResponseResult pageResponseResult = new PageResponseResult(newPageDto.getPage(), newPageDto.getSize(), (int) page.getTotal());
        pageResponseResult.setData(page.getRecords());
        return pageResponseResult;
    }

    @Override
    public void deletingCommentsReducesComments(Long entryId, Long count) {
        Integer comment = apArticleMapper.selectByEntryId(entryId);

        comment = comment - count.intValue();
        ApArticle apArticle = new ApArticle();
        apArticle.setId(entryId);
        apArticle.setComment(comment);
        apArticleMapper.updateById(apArticle);
    }
}
